package main

type Expr interface {
	accept(visitor AstVisitor) interface{}
}

type AstVisitor interface {
	visitBinary(e *Binary) interface{}
	visitGrouping(e *Grouping) interface{}
	visitLiteral(e *Literal) interface{}
	visitUnary(e *Unary) interface{}
}

type Binary struct {
	left     Expr
	operator Token
	right    Expr
}

func (e *Binary) accept(visitor AstVisitor) interface{} {
	return visitor.visitBinary(e)
}

type Grouping struct {
	expression Expr
}

func (e *Grouping) accept(visitor AstVisitor) interface{} {
	return visitor.visitGrouping(e)
}

type Literal struct {
	value interface{}
}

func (e *Literal) accept(visitor AstVisitor) interface{} {
	return visitor.visitLiteral(e)
}

type Unary struct {
	operator Token
	right    Expr
}

func (e *Unary) accept(visitor AstVisitor) interface{} {
	return visitor.visitUnary(e)
}
